/*=========================================================================
UberSim Source Code Release
-------------------------------------------------------------------------
Copyright (C) 2002 Manuela Veloso, Brett Browning, Mike Bowling,
                   James Bruce; {mmv, brettb, mhb, jbruce}@cs.cmu.edu
                   Erick Tryzelaar {erickt}@andrew.cmu.edu
School of Computer Science, Carnegie Mellon University
-------------------------------------------------------------------------
This software is distributed under the GNU General Public License,
version 2.  If you do not have a copy of this licence, visit
www.gnu.org, or write: Free Software Foundation, 59 Temple Place,
Suite 330 Boston, MA 02111-1307 USA.  This program is distributed
in the hope that it will be useful, but WITHOUT ANY WARRANTY,
including MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
-------------------------------------------------------------------------*/

#include <stdio.h>

#include "mmgr.h"

#include "CollisionGroup.h"
#include "CollisionManager.h"
#include "Spatial.h"
#include "Node.h"

/*******************************/

CollisionGroup::Collider::Collider ()
{
	spatial = 0;
	parent  = 0;
}

/*******************************/

CollisionGroup::Collider::Collider (Spatial* spatial)
{
	this->spatial = spatial;

	parent = 0;
}

/*******************************/

CollisionGroup::CollisionGroup ()
{
}

/*******************************/

CollisionGroup::~CollisionGroup ()
{
}

/*******************************/

void CollisionGroup::addCollider (Spatial* collider)
{
	for (unsigned int i = 0; i < colliders.size (); i++)
	{
		if (colliders[i].spatial == 0)
		{
			colliders[i].spatial = collider;
			return;
		}
	}

	colliders.push_back (Collider (collider));
}

/*******************************/

void CollisionGroup::addCollidee (Spatial* collidee)
{
	for (unsigned int i = 0; i < collidees.size (); i++)
	{
		if (collidees[i] == 0)
		{
			collidees[i] = collidee;
			return;
		}
	}

	collidees.push_back (collidee);
}

/*******************************/

void CollisionGroup::removeCollider (unsigned int i)
{
	if (colliders.size () > 0 && 0 <= i && i < colliders.size ())
	{
		colliders[i].spatial = 0;
	}
}

/*******************************/

void CollisionGroup::removeCollider (Spatial* collider)
{
	for (unsigned int i = 0; i < colliders.size (); i++)
	{
		if (colliders[i].spatial == collider)
		{
			colliders[i].spatial = 0;
		}
	}
}

/*******************************/

void CollisionGroup::removeCollidee (unsigned int i)
{
	if (collidees.size () > 0 && 0 <= i && i < collidees.size ())
	{
		collidees[i] = 0;
	}

}

/*******************************/

void CollisionGroup::removeCollidee (Spatial* collidee)
{
	for (unsigned int i = 0; i < collidees.size (); i++)
	{
		if (collidees[i] == collidee)
		{
			collidees[i] = 0;
		}
	}
}

/*******************************/

void CollisionGroup::testForCollisions (CollisionManager* collisionManager)
{
	unsigned int i;
	unsigned int j;
	
	Collider* collider;
	Spatial*  collidee;
	
	for (i = 0; i < colliders.size (); i++)
	{
		collider = &colliders[i];

		if (collider->spatial)
		{
			collider->parent = collider->spatial->getParent ();
			collider->parent->removeChild (collider->spatial);
			
			for (j = 0; j < collidees.size (); j++)
			{
				collidee = collidees[j];

				if (collidee)
				{
					collider->spatial->onCollidingWith (collidee);
				}
			}
		}
	}

	for (i = 0; i < colliders.size (); i++)
	{
		collider = &colliders[i];

		if (collider->spatial)
		{
			collider->parent->addChild (collider->spatial);
		}
	}
}
/*
void CollisionGroup::testCollision (CollisionManager* collisionManager, Spatial* spatial1, Spatial* spatial2)
{
	CollisionController* controller1 = spatial1->getCollisionController ();
	CollisionController* controller2 = spatial2->getCollisionController ();

	of 







	
//	printf ("testing: %s against %s\n", name, object->getName ());

	if (spatial1->getWorldBound ().isCollidingWith (spatial2->getWorldBound ()))
	{
//		printf ("%s is colliding with %s\n", name, object->getName ());

		Entity* entity = dynamic_cast<Entity*> (spatial2);

		if (entity)
		{
			collisionManager->addCollision (this, entity);
			return;
		}

		Node* node = dynamic_cast<Node*> (object);

		if (node)
		{
			for (unsigned int i = 0; i < node->size (); i++)
			{
				Spatial* child = node->getChild (i);
				if (child)
				{
					testCollision (collisionManager, child);
				}
			}

			return;
		}

		TriangleMesh* triangleMesh = dynamic_cast<TriangleMesh*> (object);

		if (triangleMesh)
		{
			collisionManager->addCollision (this, triangleMesh);
			return;
		}

		Geometry* geometry = dynamic_cast<Geometry*> (object);

		if (geometry)
		{
			collisionManager->addCollision (this, geometry);
		}
	}

}
*/
/*******************************/
